package eg.edu.eelu.fyp2013.jdetector.core.classifier;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;
import java.util.StringTokenizer;

import FullKLDA.TotalKLDA;
import KLDANeural.NKLDA;

import com.mathworks.toolbox.javabuilder.MWException;
import com.mathworks.toolbox.javabuilder.MWNumericArray;

import eg.edu.eelu.fyp2013.jdetector.core.input_output.ClassiferData;

public class UserClassification {
	
	public String []  classify (ClassiferData [] TestedUserdata) throws FileNotFoundException, MWException
	{
		File F = new File ("ClassifiedLearneddata");
		
		Scanner S = new Scanner (F);
		
		int i = 0;
		int j = 0;
		
		
		
		int numberoflearneddata = Integer.parseInt(S.nextLine());
		
		double [][] learneddata = new double [numberoflearneddata][12];
		double [] learnedlabel = new double [numberoflearneddata];
		while(S.hasNext() == true)
		{
			String line = S.nextLine();
			StringTokenizer St = new StringTokenizer(line, " ,=");
			
			int counttoken = St.countTokens();
			int count = 0;
			while(count  < counttoken)
			{
				String token = St.nextToken();
				if(count == counttoken - 1)
				{
					learnedlabel[i] = Double.parseDouble(token);
					break;
				}
				learneddata[i][j] = Double.parseDouble(token);
				j++;
		        count++;
				
			}
			count = 0;
			j = 0;
		    i++;
			
			
		}
		
		double [][] TestedMatrix = new double [TestedUserdata.length][TestedUserdata[0].Allreduceddata.size()];

		for(int p = 0; p < TestedUserdata.length; p++)
		{
			for(int o = 0; o < TestedUserdata[p].Allreduceddata.size(); o++)
			{
				TestedMatrix[p][o] = TestedUserdata[p].Allreduceddata.get(o);
			}
			
		}
		
		
		Object [] KD = new Object [3];
		  TotalKLDA Fklda = new TotalKLDA();
		  KD[0] = learneddata;
		  KD[1] = TestedMatrix;
		  KD[2] = learnedlabel;
		  
		  
	       
		  MWNumericArray [] M = new MWNumericArray[1];
		  
			      
		  Fklda.KLDA(M, KD); 
		  
		  double [] onedistance = M[0].getDoubleData();          
	   // proxy.eval("[Distance] = KLDA(Learn,Test,labels)");
	    
	    //double [][] Distancevalues = processor.getNumericArray("Distance").getRealArray2D();
	    
		double [][] Distancevalues = new double [TestedUserdata.length][numberoflearneddata];
	    int countdata = 0;
	    for(int k = 0; k < TestedUserdata.length; k++)
	    {
	    	for(int m = 0 ; m < numberoflearneddata; m++)
	    	{
	    		Distancevalues[k][m] = onedistance[countdata];
	    		countdata++;
	    	}


	    }
	    
	    String [] Testedtresult = new String [TestedUserdata.length];
	    double minlabel = 0;
	    for(int ll = 0 ; ll < TestedUserdata.length; ll++)
	    {
	    	double mindistance = Distancevalues[ll][0];
	    	minlabel = learnedlabel[0];
	    	for(int mm = 1 ; mm < numberoflearneddata; mm++)
	    	{
	    		if(Distancevalues[ll][mm]  <  mindistance)
	    		{
	    			mindistance = Distancevalues[ll][mm];
	    			minlabel = learnedlabel[mm];
	    		}
	    		 		
	    		
	    	}
	    	if(minlabel == 1)
	    	{
	    		Testedtresult [ll] = "Abnormal \n";
	    	}
	    	else if (minlabel == 0)
	    	{
	    		Testedtresult [ll] = "Normal \n";
	    	}
	    }
	    	
	    return Testedtresult;
		
		
	}

	public String []  neuralClassify (ClassiferData [] TestedUserdata) throws MWException, IOException
	{
		File F = new File ("neuralClassifiedLearneddata");
		
		Scanner S = new Scanner (F);
		
		int i = 0;
		int j = 0;
		
		
		
		int numberoflearneddata = Integer.parseInt(S.nextLine());
		
		double [][] learneddata = new double [numberoflearneddata][3060];
		double [] learnedlabel = new double [numberoflearneddata];
		while(S.hasNext() == true)
		{
			String line = S.nextLine();
			StringTokenizer St = new StringTokenizer(line, " ,=");
			
			int counttoken = St.countTokens();
			int count = 0;
			while(count  < counttoken)
			{
				String token = St.nextToken();
				if(count == counttoken - 1)
				{
					learnedlabel[i] = Double.parseDouble(token);
					break;
				}
				learneddata[i][j] = Double.parseDouble(token);
				j++;
		        count++;
				
			}
			count = 0;
			j = 0;
		    i++;
			
			
		}
		
		double [][] TestedMatrix = new double [TestedUserdata.length][TestedUserdata[0].Allreduceddata.size()];

		for(int p = 0; p < TestedUserdata.length; p++)
		{
			for(int o = 0; o < TestedUserdata[p].Allreduceddata.size(); o++)
			{
				TestedMatrix[p][o] = TestedUserdata[p].Allreduceddata.get(o);
			}
			
		}
		
		
		  Object [] KD = new Object[3];
		  NKLDA Fklda = new NKLDA(); 
		  KD[0] = learneddata;
		  KD[1] = TestedMatrix;
		  KD[2] = learnedlabel;
		  
		        
		  MWNumericArray [] M = new MWNumericArray[2];
		  Fklda.KLDAPCANeural(M, KD); 
		  
		  //double [] learnedvalues = M[0].getDoubleData();
		  double [] testedvalues =  M[1].getDoubleData(); 
		  	
			NerualNetworkClassifier t = new NerualNetworkClassifier();
			String [] testResult;
			testResult= t.multiNNclassify(testedvalues);
			double [] fulloutput = new double [testResult.length];  
			String [] Testedtresult = new String [testResult.length];
			for(int k = 0 ; k < testResult.length; k++)
			{
				fulloutput[k] = Double.parseDouble((testResult[k].substring(1, testResult[k].length()-1)));
				if (Math.round(fulloutput[k])==1)
				{
					Testedtresult [k] = "Abnormal \n";
				}
				else if (Math.round(fulloutput[k])==0)
				{
					Testedtresult [k] = "Normal \n";
				}
			}
			

	    return Testedtresult;
		
		
	}


}
